import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";

import {
  ListResourcesRequestSchema,
  ReadResourceRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";

import { getWatchDir } from "./utils.js";
import fs from "fs";
import path from "path";
import chokidar from "chokidar";

// 创建 MCP Server
const server = new Server(
  {
    name: "resource-watcher-demo",
    version: "0.1.0",
    desciption: "MCP资源列表变化监听演示",
  },
  {
    capabilities: {
      resources: {}, // 支持资源管理
    },
  }
);

// 罗列资源列表
server.setRequestHandler(ListResourcesRequestSchema, async () => {
  // 每次罗列资源的时候，都需要读取一下 assets 目录，看一下有哪些资源
  // 而不能写死，因为资源目录里面的资源有可能增加或者删除

  const watchDir = getWatchDir();
  const resources = []; // 存储最终所有的资源

  try {
    // 读取目录
    const files = fs.readdirSync(watchDir); // ["1.txt", "2.txt", ....]
    // 组装资源对象
    for (const file of files) {
      const filePath = path.join(watchDir, file);
      const stat = fs.statSync(filePath); // 该方法是查看一个资源的状态

      if (stat.isFile()) {
        // 如果进入此分支，说明当前的这个资源是一个文件资源
        resources.push({
          uri: `file://${filePath}`,
          name: file,
          mimeType: getMimeType(file),
          desciption: `文件: ${file}`,
        });
      }
    }
  } catch (err) {
    console.error(`读取资源目录时出错: ${err.message}`);
  }

  return {
    resources,
  };
});

// 读取具体的资源
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
  const { uri } = request.params;
  console.error("uri>>>", uri); // 例如：file:///Users/jie/Desktop/demo/src/assets/1.txt

  const filePath = uri.replace("file://", ""); // -> /Users/jie/Desktop/demo/src/assets/1.txt

  try {
    const content = fs.readFileSync(filePath, "utf8");
    const filename = path.basename(filePath);

    return {
      contents: [
        {
          uri,
          mimeType: getMimeType(filename),
          text: content,
        },
      ],
    };
  } catch (err) {
    console.error(`读取文件失败: ${err.message}`);
  }
});

// 获取具体的 mimetype
function getMimeType(filename) {
  const ext = path.extname(filename).toLowerCase();

  // 创建一个 mimeType 的映射对象
  const mimeTypes = {
    ".txt": "text/plain",
    ".md": "text/markdown",
    ".js": "text/javascript",
    ".json": "application/json",
    ".html": "text/html",
    ".css": "text/css",
    ".xml": "application/xml",
  };

  return mimeTypes[ext] || "text/plain";
}

// 向客户端发送通知
function sendNotification() {
  server.notification({
    method: "notifications/resources/list_changed",
    params: {},
  });
}

// 初始化一个监听器
function initWatcher() {
  // 获取监听的目录
  const watchDir = getWatchDir();

  // 创建一个监听器
  const watcher = chokidar.watch(watchDir, {
    ignored: /(^|[/\\])\../, // 忽略隐藏文件
    persistent: true, // 持久监听
    ignoreInitial: true, // 忽略初始扫描，在启动监听器的时候，第一次添加监听文件不会触发 add 一类的事件
  });

  watcher
    .on("add", () => {
      // 向客户端发送通知
      sendNotification();
    })
    .on("unlink", () => {
      // 向客户端发送通知
      sendNotification();
    });
}

const transport = new StdioServerTransport();
await server.connect(transport);

initWatcher();
